package com.water.note.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.water.note.common.BusinessException;
import com.water.note.common.PageResult;
import com.water.note.dto.TodoDTO;
import com.water.note.entity.Todo;
import com.water.note.mapper.TodoMapper;
import com.water.note.service.TodoService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 待办事项服务实现类
 */
@Service
public class TodoServiceImpl extends ServiceImpl<TodoMapper, Todo> implements TodoService {
    
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TodoDTO createTodo(Todo todo) {
        // 如果未设置优先级，则默认为普通
        if (todo.getPriority() == null) {
            todo.setPriority(0);
        }
        
        // 如果未设置状态，则默认为待办
        if (todo.getStatus() == null) {
            todo.setStatus(0);
        }
        
        // 如果未设置是否已提醒，则默认为未提醒
        if (todo.getIsReminded() == null) {
            todo.setIsReminded(0);
        }
        
        // 保存待办事项
        save(todo);
        
        // 转换为DTO返回
        return convertToDTO(todo);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TodoDTO updateTodo(Todo todo) {
        // 检查待办事项是否存在
        Todo existTodo = getById(todo.getId());
        if (existTodo == null) {
            throw new BusinessException("待办事项不存在");
        }
        
        // 检查是否是当前用户的待办事项
        if (!existTodo.getUserId().equals(todo.getUserId())) {
            throw new BusinessException("无权限修改该待办事项");
        }
        
        // 更新待办事项
        updateById(todo);
        
        // 转换为DTO返回
        return convertToDTO(todo);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTodo(Long todoId, Long userId) {
        // 检查待办事项是否存在
        Todo todo = getById(todoId);
        if (todo == null) {
            throw new BusinessException("待办事项不存在");
        }
        
        // 检查是否是当前用户的待办事项
        if (!todo.getUserId().equals(userId)) {
            throw new BusinessException("无权限删除该待办事项");
        }
        
        // 删除待办事项
        return removeById(todoId);
    }
    
    @Override
    public TodoDTO getTodoById(Long todoId) {
        // 获取待办事项
        Todo todo = getById(todoId);
        if (todo == null) {
            throw new BusinessException("待办事项不存在");
        }
        
        // 转换为DTO返回
        return convertToDTO(todo);
    }
    
    @Override
    public PageResult<TodoDTO> pageTodos(Integer page, Integer pageSize, Long userId, Integer status, String keyword) {
        // 分页查询
        Page<Todo> todoPage = new Page<>(page, pageSize);
        IPage<Todo> todoIPage = baseMapper.pageTodos(todoPage, userId, status, keyword);
        
        // 转换为DTO列表
        List<TodoDTO> todoDTOList = todoIPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        // 构建分页结果
        return new PageResult<>(page, pageSize, todoIPage.getTotal(), todoDTOList);
    }
    
    @Override
    public List<TodoDTO> listTodayTodos(Long userId) {
        // 查询今日待办事项
        List<Todo> todos = baseMapper.listTodayTodos(userId);
        
        // 转换为DTO列表
        return todos.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    @Override
    public List<TodoDTO> listOverdueTodos(Long userId) {
        // 查询已过期待办事项
        List<Todo> todos = baseMapper.listOverdueTodos(userId);
        
        // 转换为DTO列表
        return todos.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTodoStatus(Long todoId, Long userId, Integer status) {
        // 检查待办事项是否存在
        Todo todo = getById(todoId);
        if (todo == null) {
            throw new BusinessException("待办事项不存在");
        }
        
        // 检查是否是当前用户的待办事项
        if (!todo.getUserId().equals(userId)) {
            throw new BusinessException("无权限操作该待办事项");
        }
        
        // 更新状态
        return baseMapper.updateTodoStatus(todoId, status) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRemindStatus(Long todoId, Long userId, Boolean isReminded) {
        // 检查待办事项是否存在
        Todo todo = getById(todoId);
        if (todo == null) {
            throw new BusinessException("待办事项不存在");
        }
        
        // 检查是否是当前用户的待办事项
        if (!todo.getUserId().equals(userId)) {
            throw new BusinessException("无权限操作该待办事项");
        }
        
        // 更新提醒状态
        return baseMapper.updateRemindStatus(todoId, isReminded ? 1 : 0) > 0;
    }
    
    @Override
    public Map<String, Object> getOverviewData(Long userId) {
        Map<String, Object> result = new HashMap<>();
        
        // 查询待办事项总数
        LambdaQueryWrapper<Todo> countQuery = new LambdaQueryWrapper<>();
        countQuery.eq(Todo::getUserId, userId);
        long total = count(countQuery);
        result.put("count", total);
        
        // 查询已完成的待办事项数量
        LambdaQueryWrapper<Todo> completedQuery = new LambdaQueryWrapper<>();
        completedQuery.eq(Todo::getUserId, userId).eq(Todo::getStatus, 2); // 2表示已完成
        long completed = count(completedQuery);
        
        // 计算完成进度
        int progress = total > 0 ? (int) (completed * 100 / total) : 0;
        result.put("progress", progress);
        
        return result;
    }
    
    @Override
    public List<TodoDTO> getRecentTodos(Long userId, int limit) {
        // 查询最近的待办事项
        LambdaQueryWrapper<Todo> query = new LambdaQueryWrapper<>();
        query.eq(Todo::getUserId, userId)
             .orderByDesc(Todo::getCreateTime)
             .last("LIMIT " + limit);
        List<Todo> todos = list(query);
        
        // 转换为DTO返回
        return todos.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 将待办事项实体转换为DTO
     *
     * @param todo 待办事项实体
     * @return 待办事项DTO
     */
    private TodoDTO convertToDTO(Todo todo) {
        if (todo == null) {
            return null;
        }
        
        TodoDTO dto = new TodoDTO();
        BeanUtils.copyProperties(todo, dto);
        
        // 设置截止时间、完成时间、提醒时间
        if (todo.getDeadline() != null) {
            dto.setDeadline(todo.getDeadline().format(DATE_TIME_FORMATTER));
        }
        if (todo.getCompleteTime() != null) {
            dto.setCompleteTime(todo.getCompleteTime().format(DATE_TIME_FORMATTER));
        }
        if (todo.getRemindTime() != null) {
            dto.setRemindTime(todo.getRemindTime().format(DATE_TIME_FORMATTER));
        }
        
        // 设置创建时间和更新时间
        if (todo.getCreateTime() != null) {
            dto.setCreateTime(todo.getCreateTime().format(DATE_TIME_FORMATTER));
        }
        if (todo.getUpdateTime() != null) {
            dto.setUpdateTime(todo.getUpdateTime().format(DATE_TIME_FORMATTER));
        }
        
        return dto;
    }
} 